package com.pos.toolbox;


import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

public class RSAUtils {
	/**
	 * 加密算法RSA
	 */
	public static final String KEY_ALGORITHM = "RSA";

	/**
	 * 签名算法
	 */
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	/**
	 * 获取公钥的key
	 */
	private static final String PUBLIC_KEY = "RSAPublicKey";

	/**
	 * 获取私钥的key
	 */
	private static final String PRIVATE_KEY = "RSAPrivateKey";

	/**
	 * RSA最大加密明文大小
	 */
	private static final int MAX_ENCRYPT_BLOCK = 117;

	/**
	 * RSA最大解密密文大小
	 */
	private static final int MAX_DECRYPT_BLOCK = 128;
	static String pPriKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIvo3rS9dXTnb4cCFTlEULNaz26bI5Abg1r3uVE76EG/Id10fljk5yU2m1++v7ZnFj0P/Iv/I8TB2L5jNXhGbCahozQSrCZjtZA4nfjH03/DzFsyj2KcDJgk5/nXKzisJnUVWx8VVPbYXSiecg9z+ksWQXXv/H4UWZj7aBe5FYUDAgMBAAECgYBeoVBYwTh7rLnzgAYo6LsIxKg+sHH6W5GZ6qoOds2eAo/+QHfg2lo5AllPBi6XSdxxyqlPa2+e+loGVAXrZv5olTtJG9QMj3zdvBaRMNxrO6anfxdBJM/TvUFDVvfzaDxZ/5/u2x5AQTKECQPP4UfO8ARPmO5xLeQYfA7IDzQGkQJBANKZ5A/9ivFtSqHrLFixLPirrXp/UlP0XAcoB1mJYVxmsjDa5bKnO0Yyd8mw42XnhUCqf1lFHDmt1+0akze5yjsCQQCqEdcz8bI4j9fmPsEv7RSrKA2Az/CEbdIuHHC8kzjBpPZ1xDO1RSEHNaOpEMvVM0rCPbteKLKwR2apHOgToLvZAkAT8IgcT3ghRaTEUdzgBN5qKO8C4x0rX7562vpfKteyBPMoFwGaeaTuD4cx7HKLSnFeXwYxsI5sk54XD+YSZ5/TAkAvJscdlbMtz2OyaE+zc+25Dl/ACObMMI6HTkdLYR3pQk06lW0oosPndc2sQAXjVFczx129W1c/XGxwEp2dY4DxAkBcOjqMiTgd7raIjAOuogccezjgPJwAE2afR/hlPlaLEGbtPj+tCQ4UyOgOEyyx4/vdYkz8xtMogJcuWhmsM8Sm";

	static String pPubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCL6N60vXV052+HAhU5RFCzWs9umyOQG4Na97lRO+hBvyHddH5Y5OclNptfvr+2ZxY9D/yL/yPEwdi+YzV4RmwmoaM0EqwmY7WQOJ34x9N/w8xbMo9inAyYJOf51ys4rCZ1FVsfFVT22F0onnIPc/pLFkF17/x+FFmY+2gXuRWFAwIDAQAB";

	public static String encode(String text) {
		byte[] sendData;
		try {
			sendData = encryptByPublicKey(text.getBytes("utf-8"), pPubKey);
			return Base64.encodeToString(sendData);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static String decode(String text) {
		try {
			String bb = decryptByPrivateKey(Base64.decode(text), pPriKey);
			return bb;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 生成密钥对(公钥和私钥)
	 */
	public static Map<String, Object> genKeyPair() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		Map<String, Object> keyMap = new HashMap<String, Object>(2);
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		return keyMap;
	}

	/**
	 * 用私钥对信息生成数字签名
	 */
	public static String sign(byte[] data, String privatekey) throws Exception {
		PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privatekey.getBytes()));
		KeyFactory keyf = KeyFactory.getInstance("RSA");
		PrivateKey prikey = keyf.generatePrivate(priPKCS8);
		Signature signet = Signature.getInstance("MD5withRSA");
		signet.initSign(prikey);
		signet.update(data);
		byte[] signed = Base64.encodeToByte(signet.sign());
		return new String(signed, "utf-8");
	}

	/**
	 * 校验数字签名
	 */
	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
		byte[] keyBytes = Base64.decode(publicKey);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PublicKey publicK = keyFactory.generatePublic(keySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(publicK);
		signature.update(data);
		return signature.verify(Base64.decode(sign));
	}

	/**
	 * 私钥加密
	 */
	public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
		byte[] keyBytes = Base64.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	/**
	 * 公钥解密
	 */
	public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
		byte[] keyBytes = Base64.decode(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	/**
	 * 私钥解密
	 */
	public static String decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
		byte[] keyBytes = Base64.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
//		Cipher cipher = Cipher.getInstance(privateK.getAlgorithm());
		Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privateK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return new String(decryptedData, "utf-8");
	}

	/**
	 * 公钥加密
	 */
	public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
		byte[] keyBytes = Base64.decode(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
		cipher.init(Cipher.ENCRYPT_MODE, publicK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	/**
	 * 获取私钥
	 */
	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return Base64.encodeToString(key.getEncoded());
	}

	/**
	 * 获取公钥
	 */
	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return Base64.encodeToString(key.getEncoded());
	}

	public static void main(String[] args) throws Exception {
		// Map<String, Object> map = genKeyPair();
		// String privateKey = getPrivateKey(map);
		// String publicKey = getPublicKey(map);
		// System.out.println("PUBLIC_KEY: " + getPublicKey(map));
		// System.out.println("PRIVATE_KEY: " + getPrivateKey(map));
		// System.out.println(decryptByPrivateKey(encryptByPublicKey("我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯我们是中国人发货发生地方落实反馈打发时间上帝视角乐山大佛就是当时的连接服务见风使舵附近受到法律范围内无法你才是你师傅那份温暖我服务付款未付闹分手考核方法可为你开放是否违反是否可是对方客户开始的烦恼三佛后我就让我收到回复撒复合卡是否可考核范围内付款我会反馈斯蒂芬斯蒂芬福克斯".getBytes("utf-8"),
		// getPublicKey(map)), getPrivateKey(map)));
		// String source = "这是一行测试RSA数字签名的无意义文字";
		// System.out.println("原文字：\r\n" + source);
		// byte[] data = source.getBytes();
		// byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);
		// System.out.println("加密后：\r\n" + new String(encodedData));
		//// byte[] decodedData = decryptByPublicKey(encodedData, publicKey);
		//// String target = new String(decodedData);
		//// System.out.println("解密后: \r\n" + target);
		// System.err.println("私钥签名——公钥验证签名");
		// String sign = RSAUtils.sign(encodedData, privateKey);
		// System.err.println("签名:\r" + sign);
		// boolean status = RSAUtils.verify(encodedData, publicKey, sign);
		// System.err.println("验证结果:\r" + status);
		System.out.println(decryptByPrivateKey(
				"hlXK4iVWHC8f9g0u20tvRf1Zrj/01z/QTUZ+8isTQjiQ/gSvPCLgt9+PqgjCUjqtypioul6JcZKjP4lJXuaJWBDeoWvvD9VnNx6sCmgDTEls5kFzix3i+KkyKRKeEl179w9Iqku9BC5EbtSQA9ops9nVG+pjdWTPdsD92pAlU4Q="
						.getBytes("utf-8"),
				"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANwCNpBsYAc1Ub3v7TnkKCgMa1u1UHog5Vjh9gMNK8wBkFt0CKi+2NGKTy0Cy9UejhoC5OHZzraJmGH1KFzB1w3/+OWGJNNtBBqsI1vwKoB+Zdk/MwHvq1PApp/q+e5usvqlsY2ojYq3zAeOMv+N5CNXmAm5zn8X3/YwtIK10+gnAgMBAAECgYEAjBTcqRhYDD7mzQj3AuVCrD08HihUFW7cmLtG6Kp6OGrGf3RiDw90/fYSc5ZUMl5CHE27bhJAi/kQDU8LZAQH6LPYvz1YH+Gz7oypbJC/35qrQuFAjKcurGTSh9iUoORK2Dkp95sGYFPKDHr3p7RKjIvX5lmM383HuiqzNGJbKAECQQDvUr3rTjClT4JEF8dki365hDzEGO5G4aY90nJIkfoMSdPYLVDZQ2ybwRsGLSyF7lRSM5aK4WYP5NoKwoatZ189AkEA61bryc/IHltd5lPeASPQhscfi5JVxXqjLs+Vz8cDWRybyMqc+bTxlLcYFVjZ1DdfxGItxpAVVXsPqsVs+vqbMwJBAOQ1FS60/4QS/heqSRMiRXPnmf4v+76RW3FmJF34/OQM3josdATI217mU7ufBe6sZbGAydOivSz4v8Y02jGt+c0CQQDFWdjVHgdlXZ06v23WauA9hdIwSwDeX99kK/Qnj26BVfpVwYMt680Ctx/dFutkiSMoHmTgtIcPbelPfcvMFEf9AkBwqJMUaBP6bz4Eps1E15bPDxdjseptjql48fhr8phTDMElP73k0gvWYEIKAxurKt4flSL972Ohmoi173OV08/R"));
	}
}
